﻿using DingTalk.Api;
using DingTalk.Api.Request;
using DingTalk.Api.Response;
using DingTalk.Common;
using DingTalk.Service;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using static DingTalk.Api.Response.OapiV2DepartmentListsubResponse;

namespace DingWeb.Controllers.DingDing
{
    /// <summary>
    /// 核心
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class HomeController : ControllerBase
    {
        private readonly IRedisBasketRepository _cache;
        private readonly ILogger<HomeController> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="cache"></param>
        public HomeController(ILogger<HomeController> logger, IRedisBasketRepository cache)
        {
            _logger = logger;
            _cache = cache;
        }

        /// <summary>
        /// 部门和人员自动更新
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActResult AutoInfo(int k = 999)
        {
            ActResult act = new ActResult() { code = -1, msg = "操作失败" };
            if (k == 999)
            {
                try
                {
                    //防止定时重复推送执行回调      
                    string rst = _cache.Get<string>("_AutoInfo").Result;
                    if (rst == "OK")
                    {
                        _logger.LogInformation("AutoInfo:已执行过了");
                        act.msg = "已执行";
                        return act;
                    }
                    _cache.Set("_AutoInfo", "OK", TimeSpan.FromHours(1)).Wait();
                }
                catch (Exception ex)
                {
                    _logger.LogError("redis异常，不影响使用=》AutoInfo");
                }
            }
            try
            {
                // 获取token
                OapiGettokenResponse token = GetAccessToken(AppConfigurtaionHelper.Configuration["DingDing:AppKey"], AppConfigurtaionHelper.Configuration["DingDing:AppSecret"]).Result;

                if (token == null || string.IsNullOrEmpty(token.AccessToken))
                {
                    act.msg = "Token 获取失败！";
                    MailHelper.SetMail("798506003@qq.com", "定时任务异常提醒", act.msg);
                    return act;
                }

                var sql = "";
                var str = "";
                //string sql2 = @" if not EXISTS(select * from  [T_DiningStatis] where   DATEDIFF(DAY,createtime,GETDATE())=0  )
                //                 begin 
                //                insert into [T_DiningStatis]([_total],[num],[_num],[timeId],[timeName]) values(0, 0, 0, 10001, '晚餐'),(0, 0, 0, 10000, '午餐'),(0, 0, 0, 10002, '早餐'); 
                //                end ";
                //DingService.NonQuery(act, sql2);
                //拉取所有部门 
                List<DeptBaseResponseDomain> departmentlist = new List<DeptBaseResponseDomain>();
                departmentlist = GetDept(departmentlist, act, 1, token.AccessToken);
                if (departmentlist == null || departmentlist == null || departmentlist.Count < 1)
                {
                    act.msg = "拉取部门 获取失败！";
                    MailHelper.SetMail("798506003@qq.com", "定时任务异常提醒", act.msg);
                    return act;
                }

                foreach (var department in departmentlist)
                {
                    sql = sql + string.Format("('{0}','{1}','{2}',0), ", department.DeptId, department.Name, department.ParentId);
                    //根据部门拉取所有员工
                    List<OapiV2UserListResponse.ListUserResponseDomain> Userlist = new List<OapiV2UserListResponse.ListUserResponseDomain>();
                    Userlist = GetUsers(Userlist, act, department.DeptId, 0, token.AccessToken);
                    //if (Userlist == null || Userlist.Count < 1)
                    //{
                    //    //act.msg = "拉取部门员工 获取失败！";
                    //    //MailHelper.SetMail("798506003@qq.com", "定时任务异常提醒", act.msg);
                    //    //return act;
                    //    continue;
                    //}

                    if (Userlist != null && Userlist.Count > 0)
                    {
                        //根据部门存数据，默认每个部门不超过1000人
                        foreach (var user in Userlist)
                        {
                            str = str + string.Format("('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}','{14}','{15}','{16}'), ", user.Userid, user.Name, department.DeptId, department.Name, user.Avatar, user.Mobile, user.HideMobile, user.Telephone, user.JobNumber, user.Title, user.Email, user.OrgEmail, user.Remark, user.Extension, user.HiredDate, user.Active, user.Leader);
                        }
                        if (!string.IsNullOrWhiteSpace(str))
                        {
                            str = @"  INSERT INTO T_EmployeeNow([userid],[name],[deptId],[deptName],avatar,mobile,hide_mobile,telephone,job_number,title,email,org_email,remark,extension,hired_date,active,leader)   values" + str.Trim().TrimEnd(',');
                            DingService.NonQuery(act, str);
                            Userlist = new List<OapiV2UserListResponse.ListUserResponseDomain>();
                            str = "";
                        }
                    }
                }
                if (!string.IsNullOrWhiteSpace(sql))
                {
                    sql = @" INSERT INTO T_DepartmentNow([dept_id],[name],[parent_id],isDelete)   values" + sql.Trim().TrimEnd(',');
                    //if (!string.IsNullOrWhiteSpace(str))
                    //{
                    //    str = @" delete T_Employee; INSERT INTO T_Employee([userid],[name],[deptId],[deptName],avatar,mobile,hide_mobile,telephone,job_number,title,email,org_email,remark,extension,hired_date,active,leader)   values" + str.Trim().TrimEnd(',');
                    //}      
                    _logger.LogInformation(sql);
                    act = DingService.NonQuery(act, sql);
                    if (act.code == 0)
                    {
                        string str2 = @" INSERT INTO T_Employee
SELECT * FROM T_EmployeeNow WHERE isDelete=0 and userid not in (select userid from T_Employee where isdelete=0)
delete T_EmployeeNow; 
delete  T_Department;
INSERT INTO T_Department
SELECT * FROM T_DepartmentNow WHERE isDelete=0  
delete T_DepartmentNow;";
//                        string str2 = @" INSERT INTO T_Employee
//SELECT * FROM T_EmployeeNow WHERE isDelete=0 and userid not in (select userid from T_Employee where isdelete=0)
//delete T_EmployeeNow; 
// INSERT INTO T_Department
//SELECT * FROM T_DepartmentNow WHERE isDelete=0 and dept_id not in (select dept_id from T_Department where isdelete=0) 
//delete T_DepartmentNow;";
                        DingService.NonQuery(act, str2);
                    }
                }
            }
            catch (Exception ex)
            {
                act.code = -1;
                act.msg = "异常信息：" + ex.ToString();
                _logger.LogError("AutoInfo:" + ex.ToString());

                var token = GetAccessToken(AppConfigurtaionHelper.Configuration["DingDing:AppKey"], AppConfigurtaionHelper.Configuration["DingDing:AppSecret"]).Result;
                if (token != null && !string.IsNullOrEmpty(token.AccessToken))
                {
                    MessageSend(AppConfigurtaionHelper.Configuration["adminUserId"], token.AccessToken, "部门更新失败：" + ex.ToString());
                }
            }
            return act;
        }

        /// <summary>
        /// 根据部门获取员工
        /// </summary>
        /// <param name="deptId">部门id</param>
        /// <param name="deptName">部门名称</param>
        /// <returns></returns>
        [HttpPost]
        public ActResult AutoDeptEmployee(string deptId, string deptName)
        {
            ActResult act = new ActResult();
            act.code = -1;
            if (string.IsNullOrWhiteSpace(deptId))
            {
                act.msg = "部门id不能为空";
            }

            try
            {
                // 获取token
                OapiGettokenResponse token = GetAccessToken(AppConfigurtaionHelper.Configuration["DingDing:AppKey"], AppConfigurtaionHelper.Configuration["DingDing:AppSecret"]).Result;

                if (token == null || string.IsNullOrEmpty(token.AccessToken))
                {
                    act.msg = "Token 获取失败！";
                    MailHelper.SetMail("798506003@qq.com", "定时任务异常提醒", act.msg);
                    return act;
                }

                //根据部门拉取所有员工
                List<OapiV2UserListResponse.ListUserResponseDomain> Userlist = new List<OapiV2UserListResponse.ListUserResponseDomain>();
                Userlist = GetUsers(Userlist, act, long.Parse(deptId), 0, token.AccessToken);
                if (Userlist != null && Userlist.Count > 0)
                {
                    string str = "";
                    //根据部门存数据，默认每个部门不超过1000人
                    foreach (var user in Userlist)
                    {
                        str = str + string.Format("('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}','{14}','{15}','{16}'), ", user.Userid, user.Name, deptId, deptName, user.Avatar, user.Mobile, user.HideMobile, user.Telephone, user.JobNumber, user.Title, user.Email, user.OrgEmail, user.Remark, user.Extension, user.HiredDate, user.Active, user.Leader);
                    }
                    if (!string.IsNullOrWhiteSpace(str))
                    {
                        str = @"  INSERT INTO T_EmployeeNow([userid],[name],[deptId],[deptName],avatar,mobile,hide_mobile,telephone,job_number,title,email,org_email,remark,extension,hired_date,active,leader)   values" + str.Trim().TrimEnd(',');
                        DingService.NonQuery(act, str);

                    }

                    string str2 = @" INSERT INTO T_Employee
SELECT * FROM T_EmployeeNow WHERE isDelete=0 and userid not in (select userid from T_Employee where isdelete=0)
delete T_EmployeeNow; ";
                    DingService.NonQuery(act, str2);
                }
            }
            catch (Exception ex)
            {
                act.code = -1;
                act.msg = "异常信息：部门id" + deptId + "-" + ex.ToString();
                var token = GetAccessToken(AppConfigurtaionHelper.Configuration["DingDing:AppKey"], AppConfigurtaionHelper.Configuration["DingDing:AppSecret"]).Result;
                if (token != null && !string.IsNullOrEmpty(token.AccessToken))
                {
                    MessageSend(AppConfigurtaionHelper.Configuration["adminUserId"], token.AccessToken, deptName + "(部门)人员更新失败：" + ex.ToString());
                }
            }
            return act;
        }
        /// <summary>
        ///考勤：每个人当天有 上下班两条记录
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActResult AutoAttendance(int k = 999)
        {
            ActResult act = new ActResult();
            if (k == 999)
            {
                try
                {
                    //防止定时重复推送执行回调      
                    string rst = _cache.Get<string>("_AutoAttendance").Result;
                    if (rst == "OK")
                    {
                        _logger.LogInformation("AutoAttendance:已执行过了");
                        act.msg = "已执行";
                        return act;
                    }
                    _cache.Set("_AutoAttendance", "OK", TimeSpan.FromHours(1)).Wait();
                }
                catch (Exception ex)
                {
                    _logger.LogError("redis异常，不影响使用=》AutoAttendance");
                }
            }
            try
            {
                int timeType = 0;
                //14-16 保安部门考勤
                string where = @" left join T_Department d on e.deptId=d.dept_id   where d.isDelete = 0 and e.isDelete = 0 and ISNULL(d.isDing,0) = 0";
                if (DateTime.Compare(DateTime.Now, DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " 14:00:00")) > 0 && DateTime.Compare(DateTime.Now, DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " 16:00:00")) < 0)
                {
                    where = " where deptId=665050313";
                    timeType = 1;
                }

                string str = "SELECT DISTINCT e.userid  FROM T_Employee e " + where;
                string sql = "";
                string sql2 = "";
                DataTable dt = DingService.GetTable(str);
                if (dt != null && dt.Rows.Count > 0)
                {
                    // 获取token
                    OapiGettokenResponse token = GetAccessToken(AppConfigurtaionHelper.Configuration["DingDing:AppKey"], AppConfigurtaionHelper.Configuration["DingDing:AppSecret"]).Result;

                    if (token == null || string.IsNullOrEmpty(token.AccessToken))
                    {
                        act.msg = "Token 获取失败！";
                        MailHelper.SetMail("798506003@qq.com", "定时任务异常提醒", act.msg);
                        return act;
                    }

                    List<string> items = dt.AsEnumerable().Select(t => t.Field<string>("userid")).ToList();
                    List<OapiAttendanceListResponse.RecordresultDomain> Recordresultlist = new List<OapiAttendanceListResponse.RecordresultDomain>();

                    for (int i = 0; i < items.Count;)
                    {
                        Recordresultlist = GetAtt(Recordresultlist, token.AccessToken, items.GetRange(i, items.Count - i > 50 ? 50 : items.Count - i), "", "", 0);
                        i = i + 50;
                    }

                    if (Recordresultlist == null || Recordresultlist.Count < 1)
                    {
                        act.msg = "没有考勤打卡记录！";
                        MailHelper.SetMail("798506003@qq.com", "考勤", "没有考勤打卡记录");
                        return act;
                    }

                    //获取午餐打卡范围
                    string str2 = "SELECT workStart,workEnd FROM T_Time where isDelete = 0 and id = 10000";
                    DataTable dt2 = DingService.GetTable(str2);
                    if (dt2 == null || dt2.Rows.Count < 1)
                    {
                        act.msg = "没有午餐时间！";
                        MailHelper.SetMail("798506003@qq.com", "考勤", "没有设置午餐时间");
                        return act;
                    }

                    foreach (var item in Recordresultlist)
                    {
                        //合格的考勤  
                        //if (item != null && item.LocationResult == "Normal" && item.TimeResult == "Normal" && item.CheckType == "OnDuty")
                        //加班+非外勤+ 审批实例ID+审批ID
                        if (item != null && item.CheckType == "OnDuty" && item.LocationResult != "Outside" && string.IsNullOrWhiteSpace(item.ProcInstId) && item.ApproveId == 0)
                        {
                            DateTime _time = FromLongTimeStamp(item.UserCheckTime);
                            string now = DateTime.Now.ToString("yyyy-MM-dd");
                            if (timeType == 0)
                            {
                                //8 - 9点打卡 
                                if (DateTime.Compare(_time, DateTime.Parse(now + " " + dt2.Rows[0]["workStart"])) >= 0 && DateTime.Compare(_time, DateTime.Parse(now + " " + dt2.Rows[0]["workEnd"])) <= 0)
                                {
                                    sql = sql + string.Format("({0},'{1}','{2}','{3}','{4}','{5}','{6}',{7}), ", 10000, "午餐", item.Id, item.SourceType, item.UserId, "", _time, 1);
                                    sql2 = sql2 + string.Format("({0},'{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}'), ", item.Id, item.SourceType, FromLongTimeStamp(item.BaseCheckTime), FromLongTimeStamp(item.UserCheckTime), item.ProcInstId, item.ApproveId, item.LocationResult, item.TimeResult, item.CheckType, item.UserId, FromLongTimeStamp(item.WorkDate), item.RecordId, item.PlanId, item.GroupId);
                                }
                            }
                            else if (timeType == 1)
                            {
                                //14点-16点 晚餐
                                if (DateTime.Compare(_time, DateTime.Parse(now + " 14:00:00")) >= 0 && DateTime.Compare(_time, DateTime.Parse(now + " 16:00:00")) <= 0)
                                {
                                    sql = sql + string.Format("({0},'{1}','{2}','{3}','{4}','{5}','{6}',{7}), ", 10001, "晚餐", item.Id, item.SourceType, item.UserId, "", _time, 1);
                                    sql2 = sql2 + string.Format("({0},'{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}'), ", item.Id, item.SourceType, FromLongTimeStamp(item.BaseCheckTime), FromLongTimeStamp(item.UserCheckTime), item.ProcInstId, item.ApproveId, item.LocationResult, item.TimeResult, item.CheckType, item.UserId, FromLongTimeStamp(item.WorkDate), item.RecordId, item.PlanId, item.GroupId);
                                }
                            }
                        }
                    }
                }
                if (!string.IsNullOrWhiteSpace(sql))
                {
                    sql = @"insert into T_DiningVoucherNow(timeId,timeName,sourceId,source,userId,userName, userCheckTime,isUse) values" + sql.Trim().TrimEnd(',');
                    sql = sql + @" INSERT INTO T_DiningVoucher(timeId,timeName,sourceId,source,userId,userName, userCheckTime,isUse)
                                SELECT timeId,timeName,sourceId,source,userId,userName, userCheckTime,isUse FROM T_DiningVoucherNow WHERE isDelete=0 and  DATEDIFF(DAY,createtime,GETDATE())=0   and (userId+'-'+str(timeId)) not in (SELECT userId+'-'+str(timeId)  FROM [dingdingServer].[dbo].[T_DiningVoucher] where isDelete=0 and  source<>'访客码:DT_VISITOR' and  DATEDIFF(DAY,createtime,GETDATE())=0);";
                    //統計，如果已存在更新最新
                    sql = sql + @"IF OBJECT_ID('TEMPDB..#temp') IS NOT NULL
  begin 
  DROP TABLE #temp 
  end
  SELECT  timeid,timename,count(*) nums,count(*) nums2,convert(varchar(10),createtime,120) cc into #temp  FROM  [dbo].[T_DiningVoucher]  where DATEDIFF(DAY,createtime,GETDATE())=0  and isdelete=0
  group by timeid,timename,convert(varchar(10),createtime,120)    
  BEGIN 
   update a set a._total=nums,_num=nums-ISNULL(num,0)  from T_DiningStatis a join #temp as cte on  str(a.timeid)+'-'+convert(varchar(10),a.createtime,120)=(str(cte.timeid)+'-'+cc) 
  END 
 drop table #temp;";
                    sql2 = @" INSERT INTO T_Attendance([id],[sourceType],[baseCheckTime],[userCheckTime],[procInstId],[approveId],[locationResult],[timeResult],[checkType],[userId],[workDate],[recordId],[planId],[groupId])   values" + sql2.Trim().TrimEnd(',');
                    _logger.LogInformation(sql + sql2);
                    act.code = 0;
                    act.msg = "操作成功！";
                    DingService.NonQuery(act, sql + sql2);
                }
            }
            catch (Exception ex)
            {
                act.code = -1;
                act.msg = "异常信息：" + ex.ToString();
                _logger.LogError("AutoAttendance:" + ex.ToString());
                var token = GetAccessToken(AppConfigurtaionHelper.Configuration["DingDing:AppKey"], AppConfigurtaionHelper.Configuration["DingDing:AppSecret"]).Result;
                if (token != null && !string.IsNullOrEmpty(token.AccessToken))
                {
                    MessageSend(AppConfigurtaionHelper.Configuration["adminUserId"], token.AccessToken, "部门更新失败：" + ex.ToString());
                }
                MailHelper.SetMail("798506003@qq.com", "定时任务异常提醒", "ex异常：" + ex.ToString());
            }
            return act;
        }

        [HttpPost]
        public ActResult AutoAttendanceInfo(string startime, string endtime, int k = 999)
        {
            ActResult act = new ActResult();
            //默认手动执行，自动执行k=8866
            if (k == 8866)
            {
                try
                {
                    //防止定时重复推送执行回调      
                    string rst = _cache.Get<string>(k + "_AutoAttendance").Result;
                    if (rst == "OK")
                    {
                        _logger.LogInformation("AutoAttendance:已执行过了");
                        act.msg = "已执行";
                        return act;
                    }
                    _cache.Set(k + "_AutoAttendance", "OK", TimeSpan.FromHours(1)).Wait();
                }
                catch (Exception ex)
                {
                    _logger.LogError("redis异常，不影响使用=》AutoAttendance");
                }
            }
            try
            {
                string str = "SELECT DISTINCT userid  FROM T_Employee ";
                DataTable dt = DingService.GetTable(str);
                if (dt != null && dt.Rows.Count > 0)
                {
                    // 获取token
                    OapiGettokenResponse token = GetAccessToken(AppConfigurtaionHelper.Configuration["DingDing:AppKey"], AppConfigurtaionHelper.Configuration["DingDing:AppSecret"]).Result;
                    if (token == null || string.IsNullOrWhiteSpace(token.AccessToken))
                    {
                        act.msg = "Token 获取失败！";
                        MailHelper.SetMail("798506003@qq.com", "定时任务异常提醒", act.msg);
                        return act;
                    }

                    List<string> items = dt.AsEnumerable().Select(t => t.Field<string>("userid")).ToList();
                    List<OapiAttendanceListResponse.RecordresultDomain> Recordresultlist = new List<OapiAttendanceListResponse.RecordresultDomain>();

                    for (int i = 0; i < items.Count;)
                    {
                        Recordresultlist = GetAtt(Recordresultlist, token.AccessToken, items.GetRange(i, items.Count - i > 50 ? 50 : items.Count - i), startime, endtime, 0);
                        i = i + 50;

                        if (Recordresultlist != null && Recordresultlist.Count > 500)
                        {
                            Recordresultlist = InsertData(Recordresultlist);
                        }
                    }

                    if (Recordresultlist != null && Recordresultlist.Count > 0)
                    {
                        InsertData(Recordresultlist);
                    }

                    string sql2 = @"insert into T_AttendanceInfo 
                      select* from T_AttendanceNow where id not in(select id from T_AttendanceInfo); delete T_AttendanceNow;";
                    DingService.NonQuery(act, sql2);
                }
            }
            catch (Exception ex)
            {
                act.code = -1;
                act.msg = "异常信息：" + ex.ToString();
                _logger.LogError("AutoAttendance:" + ex.ToString());
                var token = GetAccessToken(AppConfigurtaionHelper.Configuration["DingDing:AppKey"], AppConfigurtaionHelper.Configuration["DingDing:AppSecret"]).Result;
                if (token != null && !string.IsNullOrEmpty(token.AccessToken))
                {
                    MessageSend(AppConfigurtaionHelper.Configuration["adminUserId"], token.AccessToken, "部门更新失败：" + ex.ToString());
                }
                //MailHelper.SetMail("798506003@qq.com", "定时任务异常提醒", "ex异常：" + ex.ToString());
            }
            return act;
        }


        private List<OapiAttendanceListResponse.RecordresultDomain> InsertData(List<OapiAttendanceListResponse.RecordresultDomain> Recordresultlist)
        {
            ActResult act = new ActResult();
            string sql2 = "";
            foreach (var item in Recordresultlist)
            {
                sql2 = sql2 + string.Format("({0},'{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}'), ", item.Id, item.SourceType, FromLongTimeStamp(item.BaseCheckTime), FromLongTimeStamp(item.UserCheckTime), item.ProcInstId, item.ApproveId, item.LocationResult, item.TimeResult, item.CheckType, item.UserId, FromLongTimeStamp(item.WorkDate), item.RecordId, item.PlanId, item.GroupId);
            }

            sql2 = @" INSERT INTO T_AttendanceNow([id],[sourceType],[baseCheckTime],[userCheckTime],[procInstId],[approveId],[locationResult],[timeResult],[checkType],[userId],[workDate],[recordId],[planId],[groupId])   values" + sql2.Trim().TrimEnd(',');
            _logger.LogInformation(sql2);
            act.code = 0;
            act.msg = "操作成功！";
            DingService.NonQuery(act, sql2);
            return new List<OapiAttendanceListResponse.RecordresultDomain>();
        }
        /// <summary>
        /// 加班申请
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActResult AutoProcesses(int k = 999, int day = 0)
        {
            ActResult act = new ActResult();
            if (k == 999)
            {
                try
                {
                    //防止定时重复推送执行回调      
                    string rst = _cache.Get<string>(day + "_AutoProcesses").Result;
                    if (rst == "OK")
                    {
                        _logger.LogInformation("AutoProcesses:已执行过了");
                        act.msg = "已执行";
                        return act;
                    }
                    _cache.Set(day + "_AutoProcesses", "OK", TimeSpan.FromHours(1)).Wait();
                }
                catch (Exception ex)
                {
                    _logger.LogError("redis异常，不影响使用=》AutoProcesses");
                }
            }

            try
            {
                string str = "SELECT DISTINCT e.userid  FROM T_Employee e left join T_Department d on e.deptId=d.dept_id   where d.isDelete = 0 and e.isDelete = 0 and ISNULL(d.isDing,0)=0";
                string sql = "";
                DataTable dt = DingService.GetTable(str);
                if (dt != null && dt.Rows.Count > 0)
                {
                    // 获取token
                    OapiGettokenResponse token = GetAccessToken(AppConfigurtaionHelper.Configuration["DingDing:AppKey"], AppConfigurtaionHelper.Configuration["DingDing:AppSecret"]).Result;

                    if (token == null || string.IsNullOrEmpty(token.AccessToken))
                    {
                        act.msg = "Token 获取失败！";
                        MailHelper.SetMail("798506003@qq.com", "定时任务异常提醒", act.msg);
                        return act;
                    }

                    List<string> items = dt.AsEnumerable().Select(t => t.Field<string>("userid")).ToList();
                    List<string> Processlist = new List<string>();

                    for (int i = 0; i < items.Count;)
                    {
                        //List<string[]> results = dt.Select().Select(dr => dr.ItemArray.Select(x => x.ToString()).ToArray()).ToList();     
                        Processlist = GetProcessIds(-day, Processlist, items.GetRange(i, items.Count - i > 10 ? 10 : items.Count - i), token.AccessToken, "0");
                        i = i + 10;
                    }

                    if (Processlist == null || Processlist.Count < 1)
                    {
                        act.msg = "没有加班数据";
                        return act;
                    }

                    //获取午餐打卡范围
                    //string str2 = "SELECT id,workStart,workEnd FROM[dingdingServer].[dbo].[T_Time] where isDelete = 0 ";
                    //DataTable dt2 = DingService.GetTable(str2);
                    //if (dt2 == null || dt2.Rows.Count < 3)
                    //{
                    //    act.msg = "请检查早中晚报餐设置！";
                    //    MailHelper.SetMail("798506003@qq.com", "考勤", "没有设置午餐时间");
                    //    return act;
                    //}

                    //string startime = "";
                    //string endtime = "";
                    //for (var i = 0; i < dt2.Rows.Count; i++)
                    //{
                    //    //晚餐
                    //    if (dt2.Rows[i]["id"].ToString() == "10001")
                    //    {
                    //        endtime = dt2.Rows[i]["workEnd"].ToString();
                    //    }
                    //    //早餐
                    //    else if (dt2.Rows[i]["id"].ToString() == "10002")
                    //    {
                    //        startime = dt2.Rows[i]["workStart"].ToString();
                    //    }
                    //    //午餐 《9  》=12
                    //}
                    foreach (var item in Processlist)
                    {
                        MessageResult<ProcessInstance> model = ProcessInstances(item, token.AccessToken).Result;
                        //同意+审批完成
                        if (model != null && model.success && model.result != null && model.result.result == "agree" && model.result.status == "COMPLETED")
                        {
                            string beginTime = "";
                            string endTime = "";
                            List<extValue> list = new List<extValue>();
                            foreach (var item2 in model.result.formComponentValues)
                            {
                                if (item2.name == "加班人" && !string.IsNullOrEmpty(item2.extValue))
                                {
                                    List<extValue> list2 = JsonConvert.DeserializeObject<List<extValue>>(item2.extValue);
                                    foreach (var item8 in list2)
                                    {
                                        list.Add(item8);
                                    }
                                }
                                else if (item2.name == "开始时间" && !string.IsNullOrEmpty(item2.value))
                                {
                                    beginTime = item2.value;
                                }
                                else if (item2.name == "结束时间" && !string.IsNullOrEmpty(item2.value))
                                {
                                    endTime = item2.value;
                                }
                            }

                            string now = DateTime.Now.ToString("yyyy-MM-dd");
                            if (day == 0)
                            {
                                //结束时间>=19点晚餐    
                                if (!string.IsNullOrWhiteSpace(endTime) && DateTime.Compare(DateTime.Parse(endTime), DateTime.Parse(now + " 19:00:00")) >= 0 && DateTime.Compare(DateTime.Parse(beginTime), DateTime.Parse(now + " 00:00:01")) >= 0)
                                {
                                    foreach (var item5 in list)
                                    {
                                        sql = sql + string.Format("({0},'{1}','{2}','{3}','{4}','{5}','{6}',{7}), ", 10001, "晚餐", model.result.businessId, model.result.title, item5.emplId, item5.name, endTime, 1);
                                    }
                                }
                            }
                            else if (day == 1)
                            {
                                //开始时间<=5点 早餐
                                if (!string.IsNullOrWhiteSpace(beginTime) && DateTime.Compare(DateTime.Parse(beginTime), DateTime.Parse(now + " 05:00:00")) <= 0 && DateTime.Compare(DateTime.Parse(beginTime), DateTime.Parse(now + " 00:00:00")) > 0)
                                {
                                    foreach (var item4 in list)
                                    {
                                        sql = sql + string.Format("({0},'{1}','{2}','{3}','{4}','{5}','{6}',{7}), ", 10002, "早餐", model.result.businessId, model.result.title, item4.emplId, item4.name, beginTime, 1);
                                    }
                                }

                                //9=12点    午餐
                                if (!string.IsNullOrWhiteSpace(beginTime) && DateTime.Compare(DateTime.Parse(beginTime), DateTime.Parse(now + " 09:00:00")) <= 0 && !string.IsNullOrWhiteSpace(endTime) && DateTime.Compare(DateTime.Parse(endTime), DateTime.Parse(now + " 12:00:00")) >= 0)
                                {
                                    foreach (var item8 in list)
                                    {
                                        sql = sql + string.Format("({0},'{1}','{2}','{3}','{4}','{5}','{6}',{7}), ", 10000, "午餐", model.result.businessId, model.result.title, item8.emplId, item8.name, beginTime, 1);
                                    }
                                }
                            }
                        }
                    }
                }

                if (!string.IsNullOrWhiteSpace(sql))
                {  //加班单
                    sql = @"insert into T_DiningVoucherNow(timeId,timeName,sourceId,source,userId,userName, userCheckTime,isUse) values" + sql.Trim().TrimEnd(',');
                    sql = sql + @" INSERT INTO T_DiningVoucher(timeId,timeName,sourceId,source,userId,userName, userCheckTime,isUse)
                                SELECT timeId,timeName,sourceId,source,userId,userName, userCheckTime,isUse FROM T_DiningVoucherNow WHERE isDelete=0 and  DATEDIFF(DAY,createtime,GETDATE())=0   and  (userId+'-'+str(timeId)) not in (SELECT userId+'-'+str(timeId)   FROM [dingdingServer].[dbo].[T_DiningVoucher] where isDelete=0 and  source<>'访客码:DT_VISITOR' and  DATEDIFF(DAY,createtime,GETDATE())=0);";

                    //sql = @"insert into T_DiningVoucher(timeId,timeName,sourceId,source,userId,userName, userCheckTime,isUse) values" + sql.Trim().TrimEnd(',');
                    //統計，如果已存在更新最新
                    sql = sql + @"IF OBJECT_ID('TEMPDB..#temp') IS NOT NULL
  begin 
  DROP TABLE #temp 
  end
  SELECT  timeid,timename,count(*) nums,count(*) nums2,convert(varchar(10),createtime,120) cc into #temp  FROM  [dbo].[T_DiningVoucher]  where DATEDIFF(DAY,createtime,GETDATE())=0  and isdelete=0
  group by timeid,timename,convert(varchar(10),createtime,120)    
  BEGIN 
   update a set a._total=nums,_num=nums-ISNULL(num,0)  from T_DiningStatis a join #temp as cte on  str(a.timeid)+'-'+convert(varchar(10),a.createtime,120)=(str(cte.timeid)+'-'+cc) 
  END 
 drop table #temp;";
                    _logger.LogInformation(sql);
                    act.code = 0;
                    act.msg = "操作成功！";
                    DingService.NonQuery(act, sql);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("AutoProcesses:" + ex.ToString());
                act.code = -1;
                act.msg = "异常信息：" + ex.ToString();
                var token = GetAccessToken(AppConfigurtaionHelper.Configuration["DingDing:AppKey"], AppConfigurtaionHelper.Configuration["DingDing:AppSecret"]).Result;
                if (token != null && !string.IsNullOrEmpty(token.AccessToken))
                {
                    MessageSend(AppConfigurtaionHelper.Configuration["adminUserId"], token.AccessToken, "部门更新失败：" + ex.ToString());
                }
                //MailHelper.SetMail("798506003@qq.com", "定时任务异常提醒", "ex异常：" + ex.ToString());
            }
            return act;
        }

        /// <summary>
        /// 获取报餐资格
        /// </summary>
        /// <returns></returns>
        //       [HttpPost]
        //       public async Task<ActResult> AutoVoucher()
        //       {
        //           ActResult act = new ActResult();
        //           try
        //           {
        //               //扫码开始不允许执行    
        //               //考勤      COMPLETED
        //               //string sql = @"insert into T_DiningVoucher(timeId,timeName,sourceId,source,userId,userName, userCheckTime,isUse)
        //               //  SELECT (select id from  T_Time where cast(cast(convert(varchar(10),getdate(),120) as datetime)+' '+workStart as datetime)<DATEADD(s, CONVERT(int,left([userCheckTime],10)) , '19700101')
        //               //          and  cast(cast(convert(varchar(10),getdate(),120) as datetime)+' '+workEnd as datetime)>DATEADD(s, CONVERT(int,left([userCheckTime],10)) , '19700101')) as timeid,
        //               //         (select name from  T_Time where cast(cast(convert(varchar(10),getdate(),120) as datetime)+' '+workStart as datetime)<DATEADD(s, CONVERT(int,left([userCheckTime],10)) , '19700101') 
        //               //          and  cast(cast(convert(varchar(10),getdate(),120) as datetime)+' '+workEnd as datetime)>DATEADD(s, CONVERT(int,left([userCheckTime],10)) , '19700101')) as timeName,
        //               //          A.[id],'考勤:'+[sourceType],E.[userId],E.name ,DATEADD(s, CONVERT(int,left([userCheckTime],10)) , '19700101') as CheckTime,1 
        //               //           FROM [dingdingServer].[dbo].[T_Attendance] A left join T_Employee E ON A.userId=E.userid where checkType='OnDuty' and timeResult='Normal'  
        //               //           and  DATEDIFF(DAY, DATEADD(s, CONVERT(int,left([userCheckTime],10)) , '19700101'), getdate())= 0  and A.isDelete=0  and  A.[id]  not in (select sourceId from T_DiningVoucher  where  isdelete=0);";
        //               //加班单
        //               string sql = @"INSERT INTO T_DiningVoucher(timeId,timeName,sourceId,source,userId,userName, userCheckTime,isUse)
        //                           SELECT (SELECT id from  T_Time where cast(cast(convert(varchar(10),getdate(),120) as datetime)+' '+workStart as datetime)<cast(REPLACE(REPLACE(p.finishTime,'T',' '),'Z','') as datetime) and  cast(cast(convert(varchar(10),getdate(),120) as datetime)+' '+workEnd as datetime)>cast(REPLACE(REPLACE(p.finishTime,'T',' '),'Z','') as datetime)) as timeid, 
        //                      (select name from  T_Time where cast(cast(convert(varchar(10),getdate(),120) as datetime)+' '+workStart as datetime)<cast(REPLACE(REPLACE(p.finishTime,'T',' '),'Z','') as datetime) and  cast(cast(convert(varchar(10),getdate(),120) as datetime)+' '+workEnd as datetime)>cast(REPLACE(REPLACE(p.finishTime,'T',' '),'Z','') as datetime)) as timeName, 
        //                           P.businessId,'加班单',E.userid,E.name,cast(REPLACE(REPLACE(p.finishTime,'T',' '),'Z','') as datetime) as finishTime,1  from T_ProcessInstance P  LEFT JOIN T_ProcessInstanceRalation
        //                           R ON P.businessId=R.businessId  LEFT JOIN  T_Employee E  
        //                           ON E.userid=R.userid
        //                           WHERE  ISNULL(E.userid,'')<>''
        //                           AND P.status='COMPLETED'  and  P.businessId not in (select sourceId from T_DiningVoucher  where  isdelete=0);";
        //               //統計，如果已存在更新最新
        //               sql = sql + @"IF OBJECT_ID('TEMPDB..#temp') IS NOT NULL
        //                             begin 
        //                            DROP TABLE #temp 
        //                             end
        // SELECT  timeid,timename,count(*) nums,count(*) nums2,convert(varchar(10),userCheckTime,120) cc into #temp  FROM  [dbo].[T_DiningVoucher]  where DATEDIFF(DAY,userCheckTime,GETDATE())=0  and isdelete=0
        // group by timeid,timename,convert(varchar(10),userCheckTime,120)   
        //  if NOT exists(SELECT * FROM    T_DiningStatis a join #temp as cte on  str(a.timeid)+'-'+convert(varchar(10),a.createtime,120)=(str(cte.timeid)+'-'+cc))
        //  BEGIN 
        //  insert into T_DiningStatis(timeid,timename,_total,_num,createtime) 
        //  select * from #temp
        //  where (str(timeid)+'-'+cc) not in (select str(timeid)+'-'+convert(varchar(10),createtime,120) from T_DiningStatis where isdelete=0)
        // END 
        // ELSE 
        // BEGIN 
        //  update a set a._total=nums,_num=nums-ISNULL(num,0)  from T_DiningStatis a join #temp as cte on  str(a.timeid)+'-'+convert(varchar(10),a.createtime,120)=(str(cte.timeid)+'-'+cc) 
        // END 
        //drop table #temp";

        //               _logger.LogInformation(sql);
        //               DingService.NonQuery(act, sql);
        //           }
        //           catch (Exception ex)
        //           {
        //               act.msg = "异常信息：" + ex.ToString();
        //               MailHelper.SetMail("798506003@qq.com", "定时任务异常提醒", "ex异常：" + ex.ToString());
        //           }
        //           return act;
        //       }

        /// <summary>
        /// 删除操作
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActResult AutoDelete(int k = 999)
        {
            ActResult act = new ActResult();
            if (k == 999)
            {
                try
                {
                    //防止定时重复推送执行回调      
                    string rst = _cache.Get<string>("_AutoDelete").Result;
                    if (rst == "OK")
                    {
                        _logger.LogInformation("AutoDelete:已执行过了");
                        act.msg = "已执行";
                        return act;
                    }
                    _cache.Set("_AutoDelete", "OK", TimeSpan.FromHours(1)).Wait();
                }
                catch (Exception ex)
                {
                    _logger.LogError("redis异常，不影响使用=》AutoProcesses");
                }
            }

            try
            {
                string sql = @" INSERT INTO T_DiningInfo
                                SELECT * FROM T_DiningVoucher WHERE isDelete=0 and id not in (SELECT id  FROM [dingdingServer].[dbo].[T_DiningInfo] where isDelete=0);
                                INSERT INTO T_EmployeeRelation(userid,code)
                                SELECT E.userid,right (D.userScanValue,18) FROM T_Employee E LEFT JOIN T_DiningVoucher D
                                ON E.userid=D.userId where ISNULL(D.userScanValue,'')<>'' and DATEDIFF(day,userCheckTime,getdate())=0 and E.userid not in(select userid from T_EmployeeRelation);

  update d set  d.userName=E.name,d.deptId=P.dept_id,d.deptName=P.name 
  FROM T_DiningInfo D
  LEFT JOIN T_Employee E ON  D.userId=E.userid
  LEFT JOIN T_Department P  ON E.deptId=P.dept_id   where DATEDIFF(DAY,D.createtime,GETDATE())=0;

  update d set  d.userName=E.name,d.deptId=P.dept_id,d.deptName=P.name 
  FROM T_AttendanceInfo D
  LEFT JOIN T_Employee E ON  D.userId=E.userid
  LEFT JOIN T_Department P  ON E.deptId=P.dept_id   where DATEDIFF(DAY,D.createtime,GETDATE())=0;

  DELETE T_DiningVoucher
  WHERE DATEDIFF(DAY,userCheckTime,getdate())>7;
  DELETE T_DiningVoucherNow
  WHERE DATEDIFF(DAY,userCheckTime,getdate())>7;
 ";
                _logger.LogInformation("执行了删除操作：" + sql);
                DingService.NonQuery(act, sql);
                act.code = 0;
            }
            catch (Exception ex)
            {
                _logger.LogError("AutoDelete:" + ex.ToString());
                var token = GetAccessToken(AppConfigurtaionHelper.Configuration["DingDing:AppKey"], AppConfigurtaionHelper.Configuration["DingDing:AppSecret"]).Result;
                if (token != null && !string.IsNullOrEmpty(token.AccessToken))
                {
                    MessageSend(AppConfigurtaionHelper.Configuration["adminUserId"], token.AccessToken, "部门更新失败：" + ex.ToString());
                }
                act.code = -1;
                act.msg = "执行异常";
            }
            return act;
        }
        /// <summary>
        /// 给没有就餐资格的人发通知
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActResult AutoSendMsg()
        {
            ActResult act = new ActResult();

            return act;
        }
        /// <summary>
        /// 扫码回调方法
        /// </summary>
        /// <param name="code"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        [HttpGet]
        public OapiV2UserGetResponse DingLoginX(string code, string state)
        {
            return DingLogin(code, state, "dingoatfattz6p1jm3rjmn", "yMYsyRei2yeBV3dJyArKUhWY9cPAsckdOHiAB7gtJ4-3dzQ_01vN97cOAFAZLu3T");
        }

        [HttpGet]
        public OapiV2UserGetResponse DingLoginY(string code, string state)
        {
            return DingLogin(code, state, "dingoadee6ouocgpqmw6ub", "tRrypDJQ6PbuVIumBcEZNN7hWioRn8rK44vWN5mkCl5SVH111y2GTRl3Lz7Q0RWo");
        }

        [HttpGet]
        public OapiV2UserGetResponse DingLoginZ(string code, string state)
        {
            return DingLogin(code, state, "dingoalhyefruwhteteepl", "FzCx9B2GVjtHqKnfEkYf-jVv5h45rmeaJCW1uixuFqjL1O1e17C42jTj7FEl1CrM");
        }

        private OapiV2UserGetResponse DingLogin(string code, string state, string qrAppId, string qrAppSecret)
        {

            OapiV2UserGetResponse rspGetResponse = new OapiV2UserGetResponse();
            try
            {
                if (string.IsNullOrWhiteSpace(qrAppId) || string.IsNullOrWhiteSpace(qrAppSecret))
                {
                    _logger.LogDebug("请先配置钉钉扫码登录信息！");
                    throw new Exception("请先配置钉钉扫码登录信息！");
                }

                //存在忽略，保证只执行一次
                //OapiV2UserGetResponse res = _cache.Get<OapiV2UserGetResponse>(qrAppId).Result;
                //if (res != null && res.Errcode == 0)
                //{
                //    _logger.LogInformation("重复的请求，忽略！");
                //    return res;
                //} 

                DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/sns/getuserinfo_bycode");
                OapiSnsGetuserinfoBycodeRequest req = new OapiSnsGetuserinfoBycodeRequest();
                // 通过扫描二维码，跳转指定的redirect_uri后，向url中追加的code临时授权码
                req.TmpAuthCode = code;
                OapiSnsGetuserinfoBycodeResponse bycodeResponse = client.Execute(req, qrAppId, qrAppSecret);

                // 获取token
                OapiGettokenResponse token = GetAccessToken(AppConfigurtaionHelper.Configuration["DingDing:AppKey"], AppConfigurtaionHelper.Configuration["DingDing:AppSecret"]).Result;
                if (token != null && token.Errcode == 0 && !string.IsNullOrEmpty(token.AccessToken))
                {
                    if (bycodeResponse != null && bycodeResponse.Errcode == 0 && bycodeResponse.UserInfo != null && !string.IsNullOrEmpty(bycodeResponse.UserInfo.Unionid))
                    {
                        // 根据unionid获取userid
                        OapiUserGetbyunionidResponse oapiUserGetbyunionidResponse = getUseridByUnionid(bycodeResponse.UserInfo.Unionid, token.AccessToken);
                        if (oapiUserGetbyunionidResponse != null && oapiUserGetbyunionidResponse.Result != null && !string.IsNullOrEmpty(oapiUserGetbyunionidResponse.Result.Userid))
                        {
                            //获取用户信息
                            rspGetResponse = GetUser(oapiUserGetbyunionidResponse.Result.Userid, token.AccessToken);
                            _cache.Set(qrAppId, rspGetResponse, TimeSpan.FromDays(1)).Wait();
                        }
                        else
                        {
                            _logger.LogInformation("OapiUserGetbyunionidResponse" + JsonHelper.ToJSON(oapiUserGetbyunionidResponse));
                        }
                    }
                    else
                    {
                        _logger.LogInformation("bycodeResponse异常" + JsonHelper.ToJSON(bycodeResponse));
                    }
                }
                else
                {
                    _logger.LogInformation("token异常" + JsonHelper.ToJSON(token));
                }

            }
            catch (Exception ex)
            {
                _logger.LogDebug("DingLogin:" + ex.ToString());
            }
            return rspGetResponse;
        }

        /// <summary>
        /// 获取token
        /// </summary>  
        [HttpGet]
        public async Task<OapiGettokenResponse> GetAccessToken(string appkey, string appsecret)
        {
            //_cache.Remove("DingdingAccessToken").Wait(); 
            OapiGettokenResponse response = new OapiGettokenResponse();
            try
            {
                try
                {
                    OapiGettokenResponse res = await _cache.Get<OapiGettokenResponse>("DingdingAccessToken");
                    if (res != null && !string.IsNullOrWhiteSpace(res.AccessToken))
                    {
                        return res;
                    }
                }
                catch (Exception ex)
                {
                    // 如果redis报错就忽略
                    _logger.LogDebug("redis:" + ex.ToString());
                    _logger.LogInformation("Redis报错了，请尽快修复");
                }

                IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
                OapiGettokenRequest request = new OapiGettokenRequest();
                request.Appkey = appkey;
                request.Appsecret = appsecret;
                request.SetHttpMethod("GET");
                response = client.Execute(request);
                if (response.Errcode == 0)
                {
                    _cache.Set("DingDingAccessToken", response, TimeSpan.FromHours(1.5)).Wait();
                    return response;
                }
            }
            catch (Exception ex)
            {
                _logger.LogDebug("GetAccessToken:" + ex.ToString());

                if (response.Errcode == 0)
                {
                    return response;
                }
            }
            return response;
        }

        #region 获取用户信息，创建修改 
        /// <summary>
        /// 根据unionid获取userid
        /// </summary>
        /// <param name="unionid">unionid是员工在当前开发者企业账号范围内的唯一标识，由系统生成</param>
        /// <param name="accesstoken">token</param>
        /// <returns></returns>
        [HttpPost]
        public OapiUserGetbyunionidResponse getUseridByUnionid(string unionid, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/getbyunionid");
            OapiUserGetbyunionidRequest request = new OapiUserGetbyunionidRequest();
            request.Unionid = unionid;
            OapiUserGetbyunionidResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 根据手机号获取用户id
        /// </summary>
        /// <param name="mobile"></param>
        /// <returns></returns> 
        [HttpPost]
        public OapiV2UserGetbymobileResponse GetByMobile(string mobile, string accesstoken)
        {
            OapiV2UserGetbymobileResponse response = new OapiV2UserGetbymobileResponse();
            if (string.IsNullOrWhiteSpace(mobile) || mobile.Length != 11)
            {
                response.ErrMsg = "手机号 必填";
                return response;
            }

            if (string.IsNullOrWhiteSpace(accesstoken))
            {
                response.ErrMsg = "accesstoken 必填";
                return response;
            }
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
            OapiV2UserGetbymobileRequest request = new OapiV2UserGetbymobileRequest();
            request.Mobile = mobile;
            response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 未登录钉钉的员工列表
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>3
        [HttpPost]
        public OapiInactiveUserV2GetResponse GetUnlogin(string date, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/inactive/user/v2/get");
            OapiInactiveUserV2GetRequest request = new OapiInactiveUserV2GetRequest();

            request.IsActive = false;//false 未登录  true 登录

            // 分页偏移量 
            request.Offset = 0L;
            // 每页size，最多100 
            request.Size = 100L;
            // 查询日期 
            request.QueryDate = date;// ("20190903");

            OapiInactiveUserV2GetResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 创建用户
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="mobile"></param>
        /// <param name="name"></param>
        /// <param name="departmentids"></param>
        /// <returns></returns>
        [HttpPost]
        public OapiV2UserCreateResponse CreateUser(string mobile, string accesstoken = "")
        {
            OapiV2UserCreateResponse rsp = new OapiV2UserCreateResponse();
            if (string.IsNullOrEmpty(accesstoken))
            {
                OapiGettokenResponse token = GetAccessToken(AppConfigurtaionHelper.Configuration["DingDing:AppKey"], AppConfigurtaionHelper.Configuration["DingDing:AppSecret"]).Result;

                if (token == null || string.IsNullOrEmpty(token.AccessToken))
                {
                    //act.msg = "Token 获取失败！";
                    MailHelper.SetMail("798506003@qq.com", "创建用户，获取token失败", "");
                    return rsp;
                }
                accesstoken = token.AccessToken;
            }


            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/create");
            OapiV2UserCreateRequest req = new OapiV2UserCreateRequest();
            req.Userid = "JPZ202301" + DateTime.Now.ToString("ddssffff");//获取当前用户id
            req.Name = "测试";
            //req.Mobile = "15077823153";
            req.Mobile = mobile;
            req.DeptIdList = "664858421";
            rsp = client.Execute(req, accesstoken);
            if (rsp.Errcode == 0)
            {
                _logger.LogDebug(rsp.ErrMsg);
                return rsp;
            }
            //rsp.ErrMsg = "失败";
            return rsp;
            //IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/create");
            //OapiUserCreateRequest request = new OapiUserCreateRequest();
            //request.Userid = userid;
            //request.Mobile = mobile;
            //request.Name = name;
            // 需要用字符串， "[100,200]" 这种格式 
            //List<long> departments = new List<long>(); 
            //departments.add(100L); 
            //departments.add(200L);

            //request.Department = departmentids;
            //OapiUserCreateResponse response = client.Execute(request, accesstoken);
            //if (response.Errcode == 0)
            //{
            //    _logger.LogDebug(response.ErrMsg);
            //    return response;
            //}
            //response.ErrMsg = "失败";
            //return response;
        }

        /// <summary>
        /// 更新用户
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        [HttpPost]
        public OapiV2UserUpdateResponse UpdateUser(string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/update");
            OapiV2UserUpdateRequest request = new OapiV2UserUpdateRequest();
            request.Userid = "zhangsan";
            request.Name = "张三";
            request.HideMobile = false;
            request.Telephone = "010-86123456-2345";
            request.JobNumber = "4";
            request.Title = "技术总监";
            request.Email = "test@xxx.com";
            request.WorkPlace = "未来park";
            request.Remark = "备注备注";
            request.DeptIdList = "2,3,4";
            OapiV2UserUpdateResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        [HttpPost]
        public OapiV2UserDeleteResponse DeleteUser(string userid, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/delete");
            OapiV2UserDeleteRequest request = new OapiV2UserDeleteRequest();
            request.Userid = userid;
            OapiV2UserDeleteResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 根据用户id获取用户信息
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        [HttpPost]
        public OapiV2UserGetResponse GetUser(string userid, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
            OapiV2UserGetRequest request = new OapiV2UserGetRequest();
            request.Userid = userid;
            request.Language = "zh_CN";
            OapiV2UserGetResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 获取部门获取用户信息
        /// </summary>
        /// <param name="departmentId">部门id</param>
        /// <param name="size">分页大小，最大100</param>
        /// <returns></returns>
        [HttpPost]
        public OapiUserSimplelistResponse GetSimplelist(long departmentId, long pageIndex, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/simplelist");
            OapiUserSimplelistRequest request = new OapiUserSimplelistRequest();
            request.DepartmentId = departmentId;
            request.Offset = pageIndex;
            request.Size = 50;
            request.Order = "entry_desc"; //entry_asc 升序

            request.SetHttpMethod("GET");
            OapiUserSimplelistResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }


        /// <summary>
        /// 获取部门获取用户详情
        /// </summary>
        /// <param name="departmentId"></param>
        /// <param name="cursor"></param>
        /// <param name="accesstoken"></param>
        /// <returns></returns>
        [HttpPost]
        public OapiV2UserListResponse GetUserlist(long departmentId, long cursor, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/list");
            OapiV2UserListRequest request = new OapiV2UserListRequest();
            request.DeptId = departmentId;
            request.Cursor = cursor;
            request.Size = 10L;
            request.OrderField = "entry_asc"; //entry_asc 升序       entry_desc降序

            request.SetHttpMethod("POST");
            OapiV2UserListResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            ///轮训调用 1秒最大掉40次
            System.Threading.Thread.Sleep(30); ;
            response.ErrMsg = "失败";
            return response;
        }
        #endregion

        #region 部门信息，子部门信息
        /// <summary>
        /// 获取部门信息
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public OapiV2DepartmentListsubResponse GetDepartment(long deptid, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
            OapiV2DepartmentListsubRequest request = new OapiV2DepartmentListsubRequest();
            request.DeptId = deptid;
            OapiV2DepartmentListsubResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            ///轮训调用 1秒最大掉40次
            System.Threading.Thread.Sleep(30);
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 获取子部门ID列表 1所有二级部门
        /// </summary>
        /// <param name="deptid"></param>
        /// <returns></returns>
        [HttpPost]
        public OapiV2DepartmentListsubidResponse GetDepartmentById(int deptid, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsubid");
            OapiV2DepartmentListsubidRequest request = new OapiV2DepartmentListsubidRequest();
            request.DeptId = deptid;
            OapiV2DepartmentListsubidResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }
        #endregion

        #region 工作通知
        /// <summary>
        /// 发送工作通知
        /// </summary> 
        /// <param name="msg">https://open.dingtalk.com/document/orgapp-server/asynchronous-sending-of-enterprise-session-messages</param>
        /// <param name="agentid"></param>
        /// <param name="useridlist"></param>
        /// <param name="accesstoken"></param>
        /// <param name="toalluser"></param>
        /// <returns></returns>
        [HttpPost]
        public OapiMessageCorpconversationAsyncsendV2Response MessageSend(string msg, int agentid, string useridlist, string accesstoken, bool toalluser = false)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
            OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
            request.AgentId = agentid;
            request.UseridList = useridlist;// "user123";
            request.ToAllUser = toalluser;

            //object request = new
            //{
            //object msg = new
            //{
            //    voice = new
            //    {
            //        duration = "100",
            //        media_id = "100"
            //    },
            //    image = new
            //    {
            //        media_id = "@123"
            //    },
            //    oa = new
            //    {
            //        head = new
            //        {
            //            bgcolor = "bgcolor",
            //            text = "text"
            //        },
            //        pc_message_url = "pc_message_url",
            //        status_bar = new
            //        {
            //            status_value = "进行中",
            //            status_bg = "0xFFF65E5E"
            //        },
            //        body = new
            //        {
            //            file_count = "file_count",
            //            image = "image",
            //            form = new
            //            {
            //                value = "value",
            //                key = "key"
            //            },
            //            author = "author",
            //            rich = new
            //            {
            //                unit = "unit",
            //                num = "num"
            //            },
            //            title = "title",
            //            content = "content"
            //        },
            //        message_url = "message_url"
            //    },
            //    file = new
            //    {
            //        media_id = "media_id"
            //    },
            //    action_card = new
            //    {
            //        btn_json_list = new
            //        {
            //            action_url = "action_url",
            //            title = "title"
            //        },
            //        single_url = "single_url",
            //        btn_orientation = "btn_orientation",
            //        single_title = "single_title",
            //        markdown = "markdown",
            //        title = "title"
            //    },
            //    link = new
            //    {
            //        picUrl = "picUrl",
            //        messageUrl = "messageUrl",
            //        text = "text",
            //        title = "title"
            //    },
            //    markdown = new
            //    {
            //        text = "text",
            //        title = "title"
            //    },
            //    text = new
            //    {
            //        content = "123"
            //    },
            //    msgtype = "text"
            //};
            //    to_all_user = "false",
            //    agent_id = "123",
            //    dept_id_list = "123,456",
            //    userid_list = "123,456"
            //};

            request.Msg = msg;
            OapiMessageCorpconversationAsyncsendV2Response response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 更新工作通知状态栏
        /// </summary> 
        /// <param name="statusvalue">https://open.dingtalk.com/document/orgapp-server/update-work-notification-status-bar</param>
        /// <param name="agentid"></param>
        /// <param name="TaskId"></param>
        /// <param name="accesstoken"></param>
        /// <returns></returns>
        [HttpPost]
        public OapiMessageCorpconversationStatusBarUpdateResponse MessageUpdate(string statusvalue, int agentid, int TaskId, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/status_bar/update");
            OapiMessageCorpconversationStatusBarUpdateRequest request = new OapiMessageCorpconversationStatusBarUpdateRequest();
            request.AgentId = agentid;
            request.StatusValue = statusvalue;// "已同意";
            request.StatusBg = "0xFF78C06E";
            request.TaskId = TaskId;
            OapiMessageCorpconversationStatusBarUpdateResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 撤销工作通知
        /// </summary>
        [HttpPost]
        public OapiMessageCorpconversationRecallResponse MessageBack(int agentid, int msgtaskid, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/recall");
            OapiMessageCorpconversationRecallRequest request = new OapiMessageCorpconversationRecallRequest();
            request.AgentId = agentid;
            request.MsgTaskId = msgtaskid;
            OapiMessageCorpconversationRecallResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }
        #endregion

        #region 代办事项

        #endregion

        /// <summary>
        /// 获取考勤信息        /// </summary>
        /// <param name="accesstoken"></param>
        /// <param name="items"></param>
        /// <param name="workdatefrom"></param>
        /// <param name="workdateto"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public OapiAttendanceListResponse GetAttendance(string accesstoken, List<string> items, string workdatefrom, string workdateto, int pageTotal = 0)
        {
            // 通过调用接口获取考勤打卡结果    
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/attendance/list");
            OapiAttendanceListRequest request = new OapiAttendanceListRequest();
            // 查询考勤打卡记录的起始工作日
            request.WorkDateFrom = workdatefrom;
            // 查询考勤打卡记录的结束工作日
            request.WorkDateTo = workdateto;
            // 员工在企业内的userid列表，最多不能超过50个。
            request.UserIdList = items;
            // 表示获取考勤数据的起始点
            request.Offset = pageTotal;
            // 表示获取考勤数据的条数，最大不能超过50条。
            request.Limit = 50;
            OapiAttendanceListResponse response = client.Execute(request, accesstoken);

            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            _logger.LogDebug(response.Errmsg);
            ///轮训调用 1秒最大掉40次
            System.Threading.Thread.Sleep(40); ;
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 获取审批模板
        /// </summary>
        /// <param name="name"></param>
        /// <param name="accesstoken"></param>
        /// <returns></returns>
        [HttpPost]
        public OapiProcessGetByNameResponse ProcessName(string name, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/process/get_by_name");
            OapiProcessGetByNameRequest req = new OapiProcessGetByNameRequest();
            // 自定义审批模板
            req.Name = name;
            OapiProcessGetByNameResponse response = client.Execute(req, accesstoken);

            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
            //            {
            //                "errcode": 0,
            //    "process_code": "PROC-C54B2B4E-BE61-4DDD-8A63-AB372E64028E",
            //    "request_id": "47fn7lwjrxyt"
            //}
        }

        /// <summary>
        /// 获取当前企业所有可管理的表单
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public dynamic Templates(string userid, string accesstoken)
        {
            string url = "https://api.dingtalk.com/v1.0/workflow/processes/managements/templates/templates?userId=" + userid;
            return HttpsHelper.Get(url, accesstoken);
        }

        /// <summary>
        /// 获取审批实例ID列表
        /// </summary>
        /// <param name="processCode"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <param name="nextToken">分页游标 默认0</param>
        /// <param name="maxResults">最多传20</param>
        /// <param name="userIds"> 最大长度10</param>
        /// <param name="accesstoken"></param>
        /// <returns></returns>
        [HttpPost]
        public MessageResult<ProcessesData> ProcessInstanceIds(int day, List<string> userIds, string accesstoken, string nextToken = "0", int maxResults = 20, string processCode = "", string startTime = "", string endTime = "")
        {
            if (string.IsNullOrWhiteSpace(processCode))
            {
                processCode = AppConfigurtaionHelper.Configuration["processCode"];
            }

            MessageResult<ProcessesData> model = new MessageResult<ProcessesData>();
            if (userIds.Count < 1 || string.IsNullOrWhiteSpace(nextToken))
            {
                return model;
            }

            string url = "https://api.dingtalk.com/v1.0/workflow/processes/instanceIds/query";
            object obj = new
            {
                processCode,
                startTime = string.IsNullOrWhiteSpace(startTime) ? DateConvertToUnixTimestamp(DateTime.Now.AddDays(day).ToString("yyyy-MM-dd") + " 00:00:00") : DateConvertToUnixTimestamp(startTime),
                endTime = string.IsNullOrWhiteSpace(endTime) ? DateConvertToUnixTimestamp(DateTime.Now.AddDays(day).ToString("yyyy-MM-dd") + " 23:59:59") : DateConvertToUnixTimestamp(endTime),
                nextToken = int.Parse(nextToken),
                maxResults,
                userIds
            };
            string postData = JsonConvert.SerializeObject(obj);
            var res = HttpsHelper.Post(url, postData, accesstoken);
            if (!string.IsNullOrWhiteSpace(res))
            {
                model = JsonConvert.DeserializeObject<MessageResult<ProcessesData>>(res);
            }
            ///轮训调用 1秒最大掉40次
            System.Threading.Thread.Sleep(30); ;
            return model;
        }

        /// <summary>
        /// 获取单个审批实例详情
        /// </summary>
        /// <param name="id"></param>
        /// <param name="accesstoken"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<MessageResult<ProcessInstance>> ProcessInstances(string id, string accesstoken)
        {
            MessageResult<ProcessInstance> data = new MessageResult<ProcessInstance>();
            string url = "https://api.dingtalk.com/v1.0/workflow/processInstances?processInstanceId=" + id;
            string res = await HttpsHelper.Get(url, accesstoken);
            if (!string.IsNullOrWhiteSpace(res))
            {
                data = JsonConvert.DeserializeObject<MessageResult<ProcessInstance>>(res);
            }
            ///轮训调用 1秒最大掉40次
            System.Threading.Thread.Sleep(30); ;
            return data;
        }

        /// <summary>
        /// 递归部门信息
        /// </summary>
        /// <param name="departmentlist"></param>
        /// <param name="act"></param>
        /// <param name="deptid"></param>
        /// <param name="accessToken"></param>
        /// <returns></returns>
        private List<DeptBaseResponseDomain> GetDept(List<DeptBaseResponseDomain> departmentlist, ActResult act, long deptid, string accessToken)
        {
            //拉取所有部门 
            OapiV2DepartmentListsubResponse list = GetDepartment(deptid, accessToken);
            if (list == null || list.Result == null || list.Result.Count < 1)
            {
                return departmentlist;
            }

            //if (departmentlist == null)
            //{
            //    departmentlist = list.Result;
            //}
            //else
            //{
            foreach (var item in list.Result)
            {
                //根据部门拉取所有员工
                departmentlist.Add(item);
                departmentlist = GetDept(departmentlist, act, item.DeptId, accessToken);
            }
            //}
            return departmentlist;
        }

        /// <summary>
        ///递归用户信息
        /// </summary>
        /// <param name="usersimplelist"></param>
        /// <param name="act"></param>
        /// <param name="deptid"></param>
        /// <param name="pageSize"></param>
        /// <param name="accessToken"></param>
        /// <returns></returns>
        private List<OapiV2UserListResponse.ListUserResponseDomain> GetUsers(List<OapiV2UserListResponse.ListUserResponseDomain> usersimplelist, ActResult act, long deptid, long pageIndex, string accessToken)
        {
            OapiV2UserListResponse list = GetUserlist(deptid, pageIndex, accessToken);
            if (list == null || list.Result == null || list.Result.List == null || list.Result.List.Count < 1)
            {
                return usersimplelist;
            }

            if (usersimplelist == null)
            {
                usersimplelist = list.Result.List;
            }
            else
            {
                // usersimplelist.Concat(list.Userlist);
                foreach (var item in list.Result.List)
                {
                    usersimplelist.Add(item);
                }
            }
            if (list.Result.HasMore)
            {
                usersimplelist = GetUsers(usersimplelist, act, deptid, list.Result.NextCursor, accessToken);
            }
            return usersimplelist;
        }

        /// <summary>
        /// 递归打卡记录
        /// </summary>
        /// <param name="Recordresultlist"></param>
        /// <param name="accesstoken"></param>
        /// <param name="items"></param>
        /// <param name="pageIndex"></param>
        /// <returns></returns>
        private List<OapiAttendanceListResponse.RecordresultDomain> GetAtt(List<OapiAttendanceListResponse.RecordresultDomain> Recordresultlist, string accesstoken, List<string> items, string beginTime, string endTime, int pageTotal = 0)
        {
            if (string.IsNullOrEmpty(beginTime))
            {
                beginTime = DateTime.Now.ToString("yyyy-MM-dd") + " 00:00:00";
                if (DateTime.Compare(DateTime.Now, DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " 12:00:00")) >= 0 && DateTime.Compare(DateTime.Now, DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " 16:00:00")) <= 0)
                {
                    beginTime = DateTime.Now.ToString("yyyy-MM-dd") + " 12:00:00";
                }
                endTime = DateTime.Now.ToString("yyyy-MM-dd") + " 23:59:59";
            }

            OapiAttendanceListResponse list = GetAttendance(accesstoken, items, beginTime, endTime, pageTotal);
            if (list == null || list.Recordresult == null || list.Recordresult.Count < 1)
            {
                return Recordresultlist;
            }

            if (Recordresultlist == null)
            {
                Recordresultlist = list.Recordresult;
            }
            else
            {
                //Recordresultlist.Concat(list.Recordresult);
                foreach (var item in list.Recordresult)
                {
                    Recordresultlist.Add(item);
                }
            }

            if (list.HasMore)
            {
                //pageIndex = pageIndex + 1;
                pageTotal = pageTotal + list.Recordresult.Count;
                Recordresultlist = GetAtt(Recordresultlist, accesstoken, items, beginTime, endTime, pageTotal);
            }
            return Recordresultlist;
        }

        /// <summary>
        /// 递归加班审核
        /// </summary>
        /// <param name="process"></param>
        /// <param name="user"></param>
        /// <param name="accessToken"></param>
        /// <param name="nextToken"></param>
        /// <returns></returns>
        private List<string> GetProcessIds(int day, List<string> process, List<string> user, string accessToken, string nextToken)
        {
            MessageResult<ProcessesData> list = ProcessInstanceIds(day, user, accessToken, nextToken);
            if (list == null || list.result == null || list.result.list.Count < 1)
            {
                return process;
            }

            if (process == null)
            {
                process = list.result.list;
            }
            else
            {
                //process.Concat(list.result.list);
                foreach (var item in list.result.list)
                {
                    process.Add(item);
                }
            }

            if (!string.IsNullOrWhiteSpace(list.result.nextToken))
            {
                process = GetProcessIds(day, process, user, accessToken, list.result.nextToken);
            }
            return process;
        }

        /// <summary>
        /// 时间转换为Unix时间戳
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        private long DateConvertToUnixTimestamp(string time)
        {
            if (string.IsNullOrWhiteSpace(time))
            {
                return 0;
            }
            DateTime dt = DateTime.Parse(time);
            DateTimeOffset dto = new DateTimeOffset(dt);
            return dto.ToUnixTimeSeconds() * 1000;
        }

        /// <summary>
        /// Unix时间转换为戳时间
        /// </summary>
        /// <param name="timeStamp"></param>
        /// <returns></returns>
        private DateTime FromLongTimeStamp(string timeStamp)
        {
            return DateTimeOffset.FromUnixTimeMilliseconds(long.Parse(timeStamp)).DateTime.ToLocalTime();
        }


        private async Task<OapiMessageCorpconversationAsyncsendV2Response> MessageSend(string useridlist, string accesstoken, string content, bool toalluser = false)
        {
            OapiMessageCorpconversationAsyncsendV2Response response = new OapiMessageCorpconversationAsyncsendV2Response();
            if (string.IsNullOrEmpty(useridlist))
            {
                response.ErrMsg = "失败";
                return response;
            }

            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
            OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
            request.AgentId = long.Parse(AppConfigurtaionHelper.Configuration["DingDing:AgentId"]);
            request.UseridList = useridlist;// "user123";
            request.ToAllUser = toalluser;

            object obj = new { msgtype = "text", text = new { content } };
            request.Msg = JsonConvert.SerializeObject(obj);
            response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

    }


    [Serializable]
    public class MessageResult<T>
    {
        public bool success { get; set; }
        public T result { get; set; }
    }

    [Serializable]
    public class ProcessesData
    {
        public List<string> list { get; set; }
        public string nextToken { get; set; }
    }

    [Serializable]
    public class ProcessInstance
    {
        public string businessId { get; set; }

        public string title { get; set; }

        public string originatorDeptId { get; set; }

        public string result { get; set; }

        public string bizAction { get; set; }

        public List<string> ccUserIds { get; set; }

        public string createTime { get; set; }

        public string originatorUserId { get; set; }

        public string originatorDeptName { get; set; }

        public string status { get; set; }

        public string finishTime { get; set; }

        public List<FormComponentValues> formComponentValues { get; set; }
    }

    [Serializable]
    public class FormComponentValues
    {
        public string componentType { get; set; }
        public string name { get; set; }
        public string bizAlias { get; set; }
        public string id { get; set; }
        public string value { get; set; }
        public string extValue { get; set; }
    }

    public class extValue
    {
        public string nick { get; set; }
        public string orgUserName { get; set; }
        public string emplId { get; set; }
        public string name { get; set; }
        public string avatar { get; set; }
        public string selectDeptId { get; set; }
        public string selectDeptName { get; set; }

    }
}
